module SessionHacker

import Atom

abstract type Session end

export JunoSession

"A Juno session"
struct JunoSession <: Session end

const ATOM_INITIAL_HANDLER = Atom.handlers["eval"]

export hack!
"""
    hack!(afunction, session)

Hijack an interactive Julia `session` by transforming text with `f` before
evaluation.

```julia
julia> using SessionHacker

julia> hack!(JunoSession()) do text
            replace(text, "and", "&")
        end

julia> true and false
false

julia> restore!(JunoSession())

julia> true and false
ERROR: syntax: extra token "and" after end of expression
```
"""
function hack!(afunction, ::JunoSession)
    Atom.handlers["eval"] = function (data)
        data["text"] = afunction(data["text"])
        ATOM_INITIAL_HANDLER(data)
    end
end

export restore!
"""
    restore!(Session)

Return a session to its original state.
"""
function restore!(::JunoSession)
    Atom.handlers["eval"] = ATOM_INITIAL_HANDLER
end

end
